
function GM:RoundController()
	GM=GAMEMODE
	rst = GetGlobalInt("ms_rndstate", 0)
	rtm = GetGlobalFloat("ms_rndtimer", 0)
	if rst==RSTATE_WAITFORPLS then
		local minpls=cvars.Number( "ms_min_players", 1 )
		if #team.GetPlayers(1)>=minpls and #team.GetPlayers(2)>=minpls then
			SetGlobalInt("ms_rndstate", RSTATE_STARTGAME)
			SetGlobalFloat("ms_rndtimer", CurTime()+cvars.Number( "ms_startup_time", 5 ))
			SendUserMessage("updateroundstate")
		end
	end
	if rst==RSTATE_STARTGAME then
		if CurTime()>rtm then
			SetGlobalInt("ms_rndstate", RSTATE_INROUND)
			SetGlobalFloat("ms_rndtimer", CurTime()+10)
			SendUserMessage("updateroundstate")
			GM.nextmap_timerstart = CurTime()
			GAMEMODE:PreRoundBegin()
		end
	end
	if rst==RSTATE_INROUND then
		if GM.round_go==false and CurTime()>rtm then
			GM.round_go=true
			for _, ply in pairs(player.GetAll()) do
				if ply:Team() == 1 or ply:Team() == 2 then
					ply:Freeze(false)
				end
			end
			
			hook.Call("RoundBegin") 
		end
		if CurTime()>rtm+(60*cvars.Number( "ms_round_timer", 3 )) then
			-- Determine round winner based on how many people alive
			local adminAlive = 0
			local mbagsAlive = 0
			local result = 0
			for _,p in pairs(team.GetPlayers(TEAM_ADMIN)) do
				if p:Alive() then adminAlive = adminAlive + 1 end
			end
			for _,p in pairs(team.GetPlayers(TEAM_MBAGS)) do
				if p:Alive() then mbagsAlive = mbagsAlive + 1 end
			end
			if adminAlive==mbagsAlive then
				SetGlobalInt("ms_rndresult", 0)
				GAMEMODE:PlaySoundToEverybody("metastrike/misc/timeover.wav")
			end
			if adminAlive>mbagsAlive then
				SetGlobalInt("ms_rndresult", TEAM_ADMIN)
				GAMEMODE:PlaySoundToEverybody("metastrike/misc/admins_victory.wav")
				team.AddScore(TEAM_ADMIN, 1)
				result = TEAM_ADMIN
			end
			if adminAlive<mbagsAlive then
				SetGlobalInt("ms_rndresult", TEAM_MBAGS)
				GAMEMODE:PlaySoundToEverybody("metastrike/misc/mingebags_victory.wav")
				team.AddScore(TEAM_MBAGS, 1)
				result = TEAM_MBAGS
			end
			-- Go to results screen
			SetGlobalInt("ms_rndstate", RSTATE_ENDROUND)
			SetGlobalFloat("ms_rndtimer", CurTime()+10)
			SendUserMessage("updateroundstate")
			hook.Call("RoundEnd", GAMEMODE, result)
		else
			-- Check for winning! conditions. -Charlie Sheen
			local adminAlive = 0
			local mbagsAlive = 0
			for _,p in pairs(team.GetPlayers(TEAM_ADMIN)) do
				if p:Alive() and p:GetObserverMode(OBS_MODE_NONE) then adminAlive = adminAlive + 1 end
			end
			for _,p in pairs(team.GetPlayers(TEAM_MBAGS)) do
				if p:Alive() and p:GetObserverMode(OBS_MODE_NONE) then mbagsAlive = mbagsAlive + 1 end
			end
			if adminAlive==0 and mbagsAlive==0 then
				GAMEMODE:PlaySoundToEverybody("metastrike/misc/draw.wav")
				SetGlobalInt("ms_rndresult", -1)
				SetGlobalInt("ms_rndstate", RSTATE_ENDROUND)
				SetGlobalFloat("ms_rndtimer", CurTime()+10)
				SendUserMessage("updateroundstate")
				hook.Call("RoundEnd", GAMEMODE, -1)
			else
				if adminAlive==0 then
					GAMEMODE:PlaySoundToEverybody("metastrike/misc/mingebags_victory.wav")
					SetGlobalInt("ms_rndresult", TEAM_MBAGS)
					team.AddScore(TEAM_MBAGS, 1)
					SetGlobalInt("ms_rndstate", RSTATE_ENDROUND)
					SetGlobalFloat("ms_rndtimer", CurTime()+10)
					SendUserMessage("updateroundstate")
					hook.Call("RoundEnd", GAMEMODE, TEAM_MBAGS)
				elseif mbagsAlive==0 then
					GAMEMODE:PlaySoundToEverybody("metastrike/misc/admins_victory.wav")
					SetGlobalInt("ms_rndresult", TEAM_ADMIN)
					team.AddScore(TEAM_ADMIN, 1)
					SetGlobalInt("ms_rndstate", RSTATE_ENDROUND)
					SetGlobalFloat("ms_rndtimer", CurTime()+10)
					SendUserMessage("updateroundstate")
					hook.Call("RoundEnd", GAMEMODE, TEAM_ADMIN)
				end
			end
		end
	end
	if rst==RSTATE_ENDROUND then
		if CurTime()>rtm then
			if (cvars.Number( "ms_map_length", 10 )>0 and CurTime()>GAMEMODE.nextmap_timerstart+(60*cvars.Number( "ms_map_length", 10 ))) 
			or (cvars.Number( "ms_map_winlimit", -1 )>0 and (team.GetScore(TEAM_MBAGS)>=cvars.Number( "ms_map_winlimit", -1 ) or team.GetScore(TEAM_ADMIN)>cvars.Number( "ms_map_winlimit", -1 ))) then
				SetGlobalInt("ms_rndstate", RSTATE_MAPCYCLE)
				for _,pl in pairs(player.GetAll()) do
					pl:Freeze(true)
					pl:SendLua("GAMEMODE:ScoreboardShow()")
				end
				GAMEMODE.nextmap_change=CurTime()+10
				return false
			end
			local minpls=cvars.Number( "ms_min_players", 1 )
			if #team.GetPlayers(1)>=minpls and #team.GetPlayers(2)>=minpls then
				game.CleanUpMap()
				SetGlobalInt("ms_rndstate", RSTATE_INROUND)
				SetGlobalFloat("ms_rndtimer", CurTime()+10)
				SendUserMessage("updateroundstate")
				GAMEMODE:PreRoundBegin()
			else
				SetGlobalInt("ms_rndstate", RSTATE_WAITFORPLS)
				SendUserMessage("updateroundstate")
			end
		end
	end
	if rst==RSTATE_MAPCYCLE then
		if CurTime()>GAMEMODE.nextmap_change and !hook.Call("PostponeMapChange") then
			if GAMEMODE.nextmapis == "Unknown" then 
				self:MSMapCycle()
			else
				game.ConsoleCommand("changelevel "..GAMEMODE.nextmapis)
			end
		end
	end
end

function GM:PreRoundBegin()
	GM=GAMEMODE
	GM:BalancePlayers()
	game.CleanUpMap()
	
	-- Support for DM maps = delete hl2 weps n shit
	for _, ent in pairs(ents.FindByClass("weapon_*")) do
		ent:Remove()
	end
	for _, ent in pairs(ents.FindByClass("item_*")) do
		ent:Remove()
	end
	
	ents.Create("info_dummy_deadlydisease")
	ents.Create("info_dummy_fire")
	-- Reset the mods
	SetGlobalString("ms_mod1","---") 
	SetGlobalString("ms_mod2","---")
	SetGlobalString("ms_mod3","---")
	-- Spawn everybody
	GM:RespawnAllPlayers()
	-- Do timers
	timer.Simple( 3, DoPreRoundMods )
	timer.Simple( 5, DoPreRoundWeapons )
	timer.Simple( 7, function() GM:PlaySoundToEverybody("metastrike/misc/cntdn_3.wav") end )
	timer.Simple( 8, function() GM:PlaySoundToEverybody("metastrike/misc/cntdn_2.wav") end )
	timer.Simple( 9, function() GM:PlaySoundToEverybody("metastrike/misc/cntdn_1.wav") end )
	timer.Simple( 10, function() GM:PlaySoundToEverybody("metastrike/misc/cntdn_0.wav") end )
	GM.round_go=false
	hook.Call("PreRoundBeginHook")
end

function GM:BalancePlayers()
	local mb = team.GetPlayers(TEAM_MBAGS)
	local ad = team.GetPlayers(TEAM_ADMIN)
	while math.abs(#mb-#ad)>1 do
		if #mb-#ad>1 then
			local move = table.Random(mb)
			move:SetTeam(TEAM_ADMIN)
			for k,v in pairs( player.GetAll() ) do
				v:ChatPrint( move:Name().." was moved to team Administrators for balance" )
			end
		elseif #ad-#mb>1 then
			local move = table.Random(ad)
			move:SetTeam(TEAM_MBAGS)
			for k,v in pairs( player.GetAll() ) do
				v:ChatPrint( move:Name().." was moved to team Mingebags for balance" )
			end
		end
		mb = team.GetPlayers(TEAM_MBAGS)
		ad = team.GetPlayers(TEAM_ADMIN)
	end
end

function GM:RespawnAllPlayers()
	-- using a function for now in case simple method is dumb
	for _, ply in pairs(player.GetAll()) do
		if ply:Team() == TEAM_HAZARD then
			ply:SetTeam(ply.OriginalTeam)
		end
		if ply:Team() == TEAM_ADMIN or ply:Team() == TEAM_MBAGS then
			ply:UnSpectate()
			ply:Spawn()
			ply:StripWeapons()
			ply:StripAmmo()
			ply:Give( "weapon_crowbar" )
			ply:SetWalkSpeed(200)
			ply:SetRunSpeed(400)
			ply:Freeze(true)
			if ply:Team()==TEAM_ADMIN then ply:SetModel("models/player/breen.mdl") ply:SetPlayerColor(Vector(0,0,0)) end
			if ply:Team()==TEAM_MBAGS then ply:SetModel("models/player/kleiner.mdl") ply:SetPlayerColor(Vector(1,1,1)) end
		end
	end
end

function DoPreRoundMods()
	GAMEMODE:DetermineRoundMods()
end

function DoPreRoundWeapons()
	if !GAMEMODE:MSCheckForMod("No Guns") then
	GAMEMODE:DetermineRoundWeapons() end
end

function GM:MSMapCycle()
	local allmaps = {}
	local maps_cs, dirs = file.Find( "maps/cs_*.bsp", "GAME" )
	table.Add(allmaps, maps_cs)
	local maps_de, dirs = file.Find( "maps/de_*.bsp", "GAME" )
	table.Add(allmaps, maps_de)
	local maps_dm, dirs = file.Find( "maps/dm_*.bsp", "GAME" )
	table.Add(allmaps, maps_dm)
	local maps_mstr, dirs = file.Find( "maps/mstr_*.bsp", "GAME" )
	table.Add(allmaps, maps_mstr)
	
	game.ConsoleCommand("changelevel "..string.sub(table.Random(allmaps),1,-5).."\n")
end